package com.workspace.js_website.service;

import com.workspace.js_website.bean.RespBean;
import com.workspace.js_website.bean.MetaBean;
import com.workspace.js_website.bean.User;
import com.workspace.js_website.bean.Role;
import com.workspace.js_website.mapper.UserMapper;
import com.workspace.js_website.mapper.RolesMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * 登录用户服务
 */

@Service
@Transactional
public class UserService implements UserDetailsService {

    private final UserMapper userMapper;
    private final RolesMapper rolesMapper;

    @Autowired
    public UserService(UserMapper userMapper, RolesMapper rolesMapper) {
        this.userMapper = userMapper;
        this.rolesMapper = rolesMapper;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //security自动调用
        //根据用户名查询用户的角色信息，并返回存入user中
        User user = userMapper.loadUserByUsername(username);
        //避免返回null，这里返回一个不含有任何值的User对象，在后期的密码比对过程中一样会验证失败
        if (user == null) {
            return new User();
        }
        List<Role> roles = rolesMapper.getRolesByUid(user.getId());
        user.setRoles(roles);
        return user;
    }

    public UserDetails loadUserByMobile(String mobile) {
        //自定义的provider手动调用
        //根据手机号查询用户的角色信息，并返回存入user中
        User user = userMapper.loadUserByMobile(mobile);
        if (user == null) {
            return null;
        }
        List<Role> roles = rolesMapper.getRolesByUid(user.getId());
        user.setRoles(roles);
        return user;
    }

    public RespBean register(User user) {
        if(!Objects.equals(user.getUsername(), "")) {
            User userByUsername = userMapper.loadUserByUsername(user.getUsername());
            if (userByUsername != null) {
                MetaBean meta = new MetaBean(400, "该用户名已被注册!");
                return new RespBean("", meta);
            }
        }
        User userByMobile = userMapper.loadUserByMobile(user.getMobile());
        if (userByMobile != null) {
            MetaBean meta = new MetaBean(400, "该手机号已被注册!");
            return new RespBean("", meta);
        }
        //生成用户UID
        user.setId(UUID.randomUUID().toString().replace("-", ""));
        //密码加密
        if(!Objects.equals(user.getPassword(), ""))
            user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
        try {
            //插入用户数据，配置用户的角色，默认都是普通用户
            userMapper.register(user);
            rolesMapper.addRoles(rolesMapper.getIdByRole("ROLE_USER"), user.getId());
            MetaBean meta = new MetaBean(200, "注册成功!");
            return new RespBean("", meta);
        } catch (Exception e) {
            //其中一个失败之后做数据库回滚操作
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            MetaBean meta = new MetaBean(400, "注册失败!");
            return new RespBean("", meta);
        }
    }

    public RespBean findBackPassword(String mobile, String newPassword) {
        User user = userMapper.loadUserByMobile(mobile);
        if (user == null){
            MetaBean meta = new MetaBean(400, "手机号未被注册!");
            return new RespBean("", meta);
        }
        newPassword = new BCryptPasswordEncoder().encode(newPassword);
        userMapper.updatePassword(user.getId(), newPassword);
        MetaBean meta = new MetaBean(200, "密码修改成功!");
        return new RespBean("", meta);
    }

    public RespBean updatePassword(User user, String oldPassword, String newPassword) {
        if (user == null) {
            MetaBean meta = new MetaBean(400, "用户尚未登录!");
            return new RespBean("", meta);
        }
        BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
        if (!bcryptPasswordEncoder.matches(oldPassword, user.getPassword())) {
            MetaBean meta = new MetaBean(400, "旧密码不正确!");
            return new RespBean("", meta);
        }
        newPassword = new BCryptPasswordEncoder().encode(newPassword);
        userMapper.updatePassword(user.getId(), newPassword);
        MetaBean meta = new MetaBean(200, "密码修改成功!");
        return new RespBean("", meta);
    }
}
